package com.gao.api.gate.quick.core.service;

import com.gao.api.gate.quick.core.async.ListenableFutureTask;
import com.gao.api.gate.quick.core.async.Listener;

import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * <p></p>
 *
 * @author gaoshuangwen
 * @since 2022/01/12 16:18
 */
public abstract class AbstractService implements Service {

    protected final AtomicBoolean running = new AtomicBoolean();

    protected final AtomicBoolean initialized = new AtomicBoolean();

    @Override
    public void start(Listener<Boolean> listener) throws ServiceException {

        if (running.compareAndSet(false, true)) {
            if (initialized.compareAndSet(false, true)) {
                init();
            }
            ListenableFutureTask<Boolean> task = new ListenableFutureTask<>(this::doStart);
            try {

                task.addListener(listener);
            } catch (Throwable e) {
                listener.onFailure(e);
                throw new ServiceException(e);
            }
        }

    }
    protected abstract boolean doStart() throws Exception;

    @Override
    public void stop(Listener<Boolean> listener) throws ServiceException {
        if (running.compareAndSet(true, false)) {
            try {
                listener.onSuccess(doStop());
            } catch (Throwable e) {
                listener.onFailure(e);
                throw new ServiceException(e);
            }
        } else {
            // 服务已经停止
            listener.onSuccess(true);
        }
    }

    protected abstract boolean doStop() throws Exception;


    @Override
    public void init() throws ServiceException {
        if (initialized.compareAndSet(false, true)) {
            try {
                doInit();
            } catch (Throwable e) {
                throw new ServiceException(e);
            }
        }
    }

    protected abstract void doInit() throws Exception;

    @Override
    public boolean isRunning() {
        return running.get();
    }


}
